package com.universest.swordholder.ui.item

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExpandLess
import androidx.compose.material.icons.filled.ExpandMore
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Slider
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.alibaba.fastjson.JSON
import com.universest.swordholder.model.config.ConfigItem
import com.universest.swordholder.tools.normallyToBoolean
import com.universest.swordholder.tools.toJsonObject
import com.universest.swordholder.ui.theme.SwordHolderTheme
import kotlin.math.roundToInt

private val defaultConfigItemTextStyle: TextStyle
    @Composable get() = MaterialTheme.typography.bodyMedium.copy(
        fontSize = 15.sp,
        color = MaterialTheme.colorScheme.onBackground,
    )

@Composable
fun ConfigItemWidget(
    modifier: Modifier = Modifier,
    configItem: ConfigItem,
    textStyle: TextStyle = defaultConfigItemTextStyle,
    value: String = "",
    onValueChange: (config: ConfigItem, value: String) ->Unit = { _, _ -> },
) {
    Column(modifier = modifier) {
        when (configItem.type) {
            "checkbox" -> {
                CheckboxItemWidget(modifier = modifier,
                    configItem = configItem,
                    textStyle = textStyle,
                    value = value,
                    onValueChange = onValueChange)
            }
            "textInput"-> {
                TextItemWidget(modifier = modifier,
                    configItem = configItem,
                    textStyle = textStyle,
                    value = value,
                    onValueChange = onValueChange)
            }
            "selector"-> {
                SelectorItemWidget(modifier = modifier,
                    configItem = configItem,
                    textStyle = textStyle,
                    value = value,
                    onValueChange = onValueChange)
            }
            "floatNumberSlider" -> {
                FloatNumberItemWidget(modifier = modifier,
                    configItem = configItem,
                    textStyle = textStyle,
                    value = value,
                    onValueChange = onValueChange)
            }
            // 可扩展其他类型
            else -> {
                Text(text = configItem.name)
            }
        }
        Text(
            text = configItem.description,
            textAlign = TextAlign.Start,
            style = textStyle.copy(
                fontSize = 12.sp,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
                fontFamily = MaterialTheme.typography.bodySmall.fontFamily),
            modifier = Modifier.padding(start = 10.dp, end = 10.dp)
        )
    }
}

@Composable
private fun FloatNumberItemWidget(
    modifier: Modifier = Modifier,
    configItem: ConfigItem,
    textStyle: TextStyle = defaultConfigItemTextStyle,
    value: String = "",
    onValueChange: (config: ConfigItem, value: String) -> Unit,
) {
    // 解析扩展属性
    val json = configItem.extensionProperty.toJsonObject()
    val maxValue = json?.getFloat("maxValue") ?: 100f
    val minValue = json?.getFloat("minValue") ?: 0f
    val decimalPlaces = json?.getIntValue("decimalPlaces") ?: 2

    // 将字符串值转换为Float，如果转换失败则使用默认值
    val currentValue = try {
        value.toFloat()
    } catch (e: NumberFormatException) {
        configItem.defaultValue.toFloatOrNull() ?: minValue
    }.coerceIn(minValue, maxValue)

    // 格式化显示的值，保留指定小数位数
    val formattedValue = String.format("%.${decimalPlaces}f", currentValue)

    Column(modifier = modifier) {
        Text(
            text = configItem.name,
            textAlign = TextAlign.Start,
            style = textStyle.copy(fontWeight = FontWeight.Bold),
            modifier = Modifier.padding(start = 10.dp, top = 10.dp)
        )

        // 显示当前数值
        Text(
            text = formattedValue,
            style = textStyle.copy(
                fontWeight = FontWeight.Bold,
                color = MaterialTheme.colorScheme.primary
            ),
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 10.dp, vertical = 5.dp)
                .align(Alignment.CenterHorizontally),
            textAlign = TextAlign.Center
        )

        // 显示数值范围
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(start = 10.dp, end = 10.dp, bottom = 5.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                text = String.format("%.${decimalPlaces}f", minValue),
                style = textStyle.copy(
                    fontSize = 12.sp,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            )
            Slider(
                value = currentValue,
                onValueChange = { newValue ->
                    // 根据小数位数进行精度处理
                    val adjustedValue = if (decimalPlaces == 0) {
                        newValue.roundToInt().toFloat()
                    } else {
                        val factor = 10f.pow(decimalPlaces)
                        (newValue * factor).roundToInt() / factor
                    }
                    onValueChange(configItem, adjustedValue.toString())
                },
                valueRange = minValue..maxValue,
                modifier = Modifier.weight(1f)
            )
            Text(
                text = String.format("%.${decimalPlaces}f", maxValue),
                style = textStyle.copy(
                    fontSize = 12.sp,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            )
        }
    }
}

// 为Float添加幂运算的扩展函数
private fun Float.pow(n: Int): Float {
    var result = 1f
    repeat(n) {
        result *= this
    }
    return result
}

@Composable
private fun SelectorItemWidget(
    modifier: Modifier = Modifier,
    configItem: ConfigItem,
    textStyle: TextStyle = defaultConfigItemTextStyle,
    value: String = "",
    onValueChange: (config: ConfigItem, value: String) -> Unit,
) {
    val text = value
    val json = configItem.extensionProperty.toJsonObject()
    val options = json?.getJSONArray("options")?.map { it.toString() } ?: emptyList()

    // 控制下拉菜单显示状态
    var expanded by remember { mutableStateOf(false) }

    Column(modifier = modifier) {
        Text(
            text = configItem.name,
            textAlign = TextAlign.Start,
            style = textStyle.copy(fontWeight = FontWeight.Bold),
            modifier = Modifier.padding(start = 10.dp, top = 10.dp)
        )

        // 下拉菜单触发区域（显示当前选中值和箭头）
        Box(modifier = Modifier.padding(start = 10.dp, end = 10.dp, top = 10.dp)){
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .background(
                        color = MaterialTheme.colorScheme.background,
                        shape = MaterialTheme.shapes.small
                    )
                    .border(1.dp, MaterialTheme.colorScheme.outline,MaterialTheme.shapes.small)
                    .padding(5.dp)
                    .height(25.dp)
                    .clickable { expanded = !expanded }, // 点击切换菜单显示状态
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    text = value.ifEmpty { "请选择" }, // 显示当前选中值，默认提示文字
                    style = textStyle.copy(color = if (value.isEmpty()) textStyle.color.copy(alpha = 0.6f) else textStyle.color),
                    modifier = Modifier.weight(1f)
                )
                Icon(
                    imageVector = if(expanded)Icons.Default.ExpandLess else Icons.Default.ExpandMore,
                    contentDescription = "展开菜单",
                    modifier = Modifier.padding(start = 4.dp),
                    tint = MaterialTheme.colorScheme.onBackground
                )
            }
        }
        var boxWidth by remember { mutableStateOf(0) }

        Box(modifier = Modifier
            .fillMaxWidth()
            .padding(bottom = 10.dp, start = 10.dp, end = 10.dp)
            .onSizeChanged { size ->
                boxWidth = size.width
            }) {

            DropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false },
                modifier = Modifier
                    .width(with(LocalDensity.current) { boxWidth.toDp() })
            ) {
                options.forEach { option ->
                    DropdownMenuItem(
                        text = { Text(text = option) },
                        onClick = {
                            onValueChange(configItem, option)
                            expanded = false
                        }
                    )
                }
            }
        }
    }
}

@Composable
private fun TextItemWidget(
    modifier: Modifier = Modifier,
    configItem: ConfigItem,
    textStyle: TextStyle = defaultConfigItemTextStyle,
    value: String = "",
    onValueChange: (config: ConfigItem, value: String) ->Unit,
) {
    val text = value
    Column(modifier = modifier) {
        Text(
            text = configItem.name,
            textAlign = TextAlign.Start,
            style = textStyle.copy(fontWeight = FontWeight.Bold),
            modifier = Modifier.padding(start = 10.dp,top = 10.dp)
        )
        Box(modifier = Modifier.fillMaxWidth()
            .wrapContentHeight().padding(10.dp)){
            BasicTextField(
                value = text,
                onValueChange = {
                    onValueChange(configItem, it)
                },
                cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), // 光标颜色
                modifier = Modifier
                    .background(
                        color = MaterialTheme.colorScheme.background,
                        shape = MaterialTheme.shapes.small
                    )
                    .border(1.dp, MaterialTheme.colorScheme.outline,MaterialTheme.shapes.small)
                    .fillMaxWidth()
                    .padding(5.dp)
                    .height(25.dp),
                singleLine = true,
                textStyle = textStyle.copy(
                    color = MaterialTheme.colorScheme.onBackground,
                    textAlign = TextAlign.Start,
                ),
            )
        }
    }
}

@Composable
private fun CheckboxItemWidget(
    modifier: Modifier = Modifier,
    configItem: ConfigItem,
    textStyle: TextStyle = defaultConfigItemTextStyle,
    value: String = "",
    onValueChange: (config: ConfigItem, value: String) ->Unit,
) {
    val checked = value.normallyToBoolean()
    Row(modifier = modifier
        .clickable(onClick = {
            onValueChange(configItem, (!checked).toString())
        }), verticalAlignment = Alignment.CenterVertically) {
        Text(
            text = configItem.name,
            textAlign = TextAlign.Start,
            style = textStyle.copy(fontWeight = FontWeight.Bold),
            modifier = Modifier.padding(start = 10.dp)
        )
        Box(modifier = Modifier.weight(1f))
        Switch(
            modifier = Modifier.padding(end = 10.dp).scale(0.8f),
            checked = checked,
            onCheckedChange = {
                onValueChange(configItem, it.toString())
            },
        )
    }
}

@Preview
@Composable
fun ConfigItemScreenPreview() {
    val configItem = ConfigItem(
        key = "test",
        type = "checkbox",
        name = "测试配置项",
        defaultValue = "true",
        description = "test",
        extensionProperty = "test"
    )
    val configItem2 = ConfigItem(
        key = "test",
        type = "textInput",
        name = "模型地址",
        defaultValue = "https://www.ww.ww",
        description = "在此输入模型地址。",
        extensionProperty = "test"
    )
    val configItem3 = ConfigItem(
        key = "test",
        type = "selector",
        name = "模型选择",
        defaultValue = "deepseek",
        description = "在此输入模型地址。",
        extensionProperty = "{\"options\":[\"deepseek\"]}"
    )
    val configItem4 = ConfigItem(
        key = "volume",
        type = "floatNumberSlider",
        name = "音量大小",
        defaultValue = "0.5",
        description = "通过拖曳滑块调整音量大小",
        extensionProperty = "{\"minValue\": -2.0, \"maxValue\": 2.0, \"decimalPlaces\": 2}"
    )
    SwordHolderTheme {
        var booleanVar by remember { mutableStateOf("true") }
        Column(modifier = Modifier
            .background(MaterialTheme.colorScheme.background)
            .fillMaxSize()) {
            ConfigItemWidget(
                configItem = configItem,
                value = booleanVar,
                onValueChange = { _, value -> booleanVar = value }
            )
            var text by remember { mutableStateOf("https://www.ww.ww") }
            ConfigItemWidget(
                configItem = configItem2,
                value = text,
                onValueChange = {
                        configItem, str -> text = str
                }
            )
            var option by remember { mutableStateOf("deepseek") }
            ConfigItemWidget(
                configItem = configItem3,
                value = option,
                onValueChange = {
                        configItem, str -> option = str
                }
            )
            var volume by remember { mutableStateOf("1.5") }
            ConfigItemWidget(
                configItem = configItem4,
                value = volume,
                onValueChange = {
                        configItem, str -> volume = str
                }
            )
        }
    }
}